import router from '@/router'
import store from '@/store'
/**
 * Nprogress细节问题注意
 *  其实应该不能说是nprogress的问题，是我们路由守卫的问题
 *  当我们直接next放行的时候-next()，能走进afterEach
 *  当我们使用next('/xxx') 不会走afterEach
 *
 */
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// import { asyncRoutes } from '@/router'

NProgress.configure({ showSpinner: false })

/**
 * to 去哪里
 * from 从哪来
 * next 放行函数
 *  next() 放行
 *  next('/xxx') 去xxx
 *  next(参数) 和我们的router.push的参数语法是一致
 *      // 字符串
        router.push('home')

        // 对象
        router.push({ path: 'home' })

        // 命名的路由
        router.push({ name: 'user', params: { userId: '123' }})

        // 带查询参数，变成 /register?plan=private
        router.push({ path: 'register', query: { plan: 'private' }})

    容易出错的点
    1. 判断是否是登录页 to.path === '/login' 注意是/login 不是login
    2. 我们判断是否登录 store.getters.token 这个东西写在beforeEach还是外面
        写在外面只执行一次
        写在里面每去一个页面都会执行
 */
// console.log('写在外面')
// 白名单 登录页 404
const whiteList = ['/login', '/404']
// 前置守卫
router.beforeEach(async(to, from, next) => {
  console.log(to)
  // 进度条开始
  NProgress.start()
  //   console.log(to)
  //   next()
  const token = store.getters.token
  if (token) {
    // 登录了
    if (to.path === '/login') {
      // 登录了再去登录页 直接跳到主(首)页
      // 这里是直接放行next() 语法嘛？因为不是，是直接跳转其他页面所以不走afterEach
      NProgress.done()
      next('/')
    } else {
      // 登录了去其他页面 直接放行
      // 发送请求，拿到用户的资料，控制他的权限
      /**
       * 需求
       *  如果不做处理，我们每进一个页面都会发送请求，这样明显不合理
       *  但我们第一次肯定要发请求
       *  后续进入页面就不需要发了
       * 实现方式
       *  因为不发请求 userInfo是个空对象
       *  发了请求 不是空对象 有很多字段数据
       *  判断这个对象里有没有userId，
       *    有的话 发送过请求了
       *    没有的话 说明没发过 - 第一次需要发送请求
       *
       */
      if (!store.state.user.userInfo.userId) {
        const res = await store.dispatch('user/getUserInfo')
        // menus 用户自己能看到的菜单，自己的权限能看什么 是个数组里面每一项字符串 路由规则中的name对应的
        const menus = res.roles.menus
        // console.log(menus)
        // 筛选路由 放行通过
        // 动态路由按需导出了 可以导入拿到
        /**
         *  router.addRoutes - 动态添加路由 是router实例的方法
         * 语法
         * router.addRoutes是个函数 参数是数组，数组里的每一项是个对象，对象的属性就是我们配置的路由信息规则(和之前路由配置一样)
         *  举例 [{path: '/xxx', component: yyy}, {path: '/zzz', component: aaa, name: ...}]
         * 固定写法
         *  在调用addRoutes后 要直接“回首掏”
         *  next({...to, replace: true})
         */
        // 动态添加路由 有两个问题 第一个问题左侧菜单不显示 第二个 第一次通过url访问对应的路由模块再次刷新会404
        // 是加所有的动态路由吗？应该要做过滤 静态的路由 + 过滤后的路由
        // 所有的动态路由 asyncRoutes 用户能看到的菜单 menus
        // 实现的功能 就是调用vuex中的action 获取到过滤后的菜单
        const otherRoutes = await store.dispatch('permission/filterRoutes', menus)
        // console.log(otherRoutes)
        router.addRoutes([
          ...otherRoutes,
          { path: '*', redirect: '/404', hidden: true }
        ])
        // 固定写法，必须回首掏 目的是为了确保路由加载完毕
        next({ ...to, replace: true })
        // router.options.routes 只能拿到默认配置的
        // 注意router.options.routes他不是响应式的，这个是之前vuerouter设计就是这样的，并且他也没提供什么解决方案让他响应式
        // setTimeout(() => {
        //   console.log(router.options.routes)
        // }, 5000)
        // 需要return 否则下面会继续执行 回首掏已经重新进入页面了
        return
      }
      next()
    }
  } else {
    // 没登录
    // 判断是否去白名单
    if (whiteList.includes(to.path)) {
      // 没登录去白名单 放行
      next()
    } else {
      // 没登录不去白名单 直接去登录页
      // 因为不是直接放行的语法next(),而是去登录页，所以也不走afterEach
      NProgress.done()
      next('/login')
    }
  }
})
// 后置守卫
// afterEach 参数 - 回调函数 回调函数的参数就2个，一个to一个from，没有next原因是因为进入到这个页面不需要放行
router.afterEach((to, from) => {
  // console.log('走afterEach了')
  // 进度条直接走完
  NProgress.done()
})
